#include <iostream>

#if 0
    // 静态成员变量
    class Test
    {
    public:

    public:
        // 静态成员变量（static在C++里去修饰成员变量，但其本质还是静态变量）
        // 它的空间在静态区，不属于某个特定的对象，属于整个类
        // 普通成员变量在构造函数中初始化，但是静态成员变量不属于某个对象，所以它没有办法在构造函数中初始化
        // 如果静态成员变量属于某个对象而它又在静态区的话，那就意味着每构建一个类的对象，就会在静态区出现一个变量，那静态区得有多少这样的变量，要知道，静态区的变量是没有办法释放的，栈上堆上构建的对象到时候会让静态区充满了这样的变量，所以静态变量只能由所有类的对象共享
        static int a;   // 这句话充其量只能算是一个声明，真正要用它得在类外初始化定义   
    };

    // 不能在构造函数中初始化，只能在类外单独定义
    int Test::a = 0;

    int main()
    {
        Test t;
        Test t2;
        t.a++; // 如果静态成员变量不在类外进行初始化，是未定义的，会报错
        std::cout<<t2.a<<std::endl;
        std::cout<<sizeof(t)<<std::endl;    // 一个字节 所以很显然这个a一定不占对象的内存
        return 0;
    }
#endif

#if 0
    // 静态成员变量用法1：
    // 用来检测一个类的对象是否有泄露情况
    class Test
    {
    public:
        Test()
        {
            a++;
        }

        ~Test()
        {
            a--;
        } 

    public:
        static int a;    
    };

    int Test::a = 0;

    int main()
    {
        Test *t1 = new Test;
        Test *t2 = new Test;

        delete t1;
        // delete t2;

        // 用来检测一个类的对象是否有泄露情况
        std::cout<<Test::a<<std::endl;  // 由于它属于整个类，所以它可以直接由类去访问    
        return 0;
    }
#endif

#if 1
    // 静态成员变量用法2：
    // 静态成员函数可以使用静态成员变量
    class Test
    {
    public:
        Test()
        {
    
        }

        // 静态成员函数（不属于某个特定对象，属于整个类）
        // 1、没有办法使用普通成员变量
        // 2、不需要依赖对象调用（由第一点知：它和对象本身依赖度不高，它可以直接与普通对象分离）
        // 3、可以使用静态成员变量
        static void func()  
        {
            // b++;    // 非静态成员引用必须与特定对象相对，也就代表这个函数不属于这个对象，它属于整个类
            a++;       // 可以使用静态成员变量
        }

        void show()
        {
            std::cout<<"helloworld"<<std::endl;
        }

        ~Test()
        {
            
        } 

    public:
        static int a;
        int b;    
    };

    int Test::a = 0;
    

    int main()
    {
        // 普通函数的调用必须依赖对象
        Test t;
        t.show(); // 正常使用这个show函数，经编译器会翻译成：show(&t);这就说明这个函数的使用要依赖对象
        // Test::show(); // 普通成员函数不能单独出现，也就是不能只靠作用域出现   
        Test::func();
        return 0;
    }
#endif